package com.myl.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//import org.apache.poi.ss.usermodel.DateUtil;

/**
 * DateUtils
 * author: myl <ixiaomu@qq.com>
 * tips:
 */
public class DateUtils {
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 季节终止日期
     */
    private static final List<String> seasonsDate = Arrays.asList("0331", "0630", "0930", "1231");

    public static Date getLastYearToday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.YEAR, -1);
        return cal.getTime();
    }

    public static Date getLastMonthToday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, -1);
        return cal.getTime();
    }

    public static String formatDateTime(long mss) {
        long days = mss / 86400L;
        long hours = mss % 86400L / 3600L;
        long minutes = mss % 3600L / 60L;
        long seconds = mss % 60L;
        String dateTimes;
        if (days > 0L) {
            dateTimes = days + "天" + hours + "小时" + minutes + "分钟" + seconds + "秒";
        } else if (hours > 0L) {
            dateTimes = hours + "小时" + minutes + "分钟" + seconds + "秒";
        } else if (minutes > 0L) {
            dateTimes = minutes + "分钟" + seconds + "秒";
        } else {
            dateTimes = seconds + "秒";
        }

        return dateTimes;
    }

    /**
     * 格式化日期，时分秒重置为0
     *
     * @param pattern
     * @param originDate
     * @return
     * @throws ParseException
     */
    public static Date formatDate(String pattern, Date originDate) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            String dateStr = dateFormat.format(originDate);
            return dateFormat.parse(dateStr);
        } catch (Exception e) {
            throw new RuntimeException("格式化日期出错");
        }
    }

    /**
     * 格式化日期
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String dateToString(Date date, String pattern) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            return dateFormat.format(date);
        } catch (Exception e) {
            throw new RuntimeException("格式化日期出错");
        }
    }

    /**
     * 返回输入日期所在周的周一和周日的日期
     *
     * @param time 输入日期
     * @return map集合, map.get("first")为所在周周一的日期,yyyy-MM-dd格式 ；map.get("last")为所在周周日的日期,yyyy-MM-dd格式
     */
    public static Map<String, String> convertWeekByDate(Date time) {
        Map<String, String> map = new HashMap<String, String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        String imptimeBegin = sdf.format(cal.getTime());
        System.out.println("所在周星期一的日期：" + imptimeBegin);
        cal.add(Calendar.DATE, 6);
        String imptimeEnd = sdf.format(cal.getTime());
        System.out.println("所在周星期日的日期：" + imptimeEnd);

        map.put("first", imptimeBegin);

        map.put("last", imptimeEnd);

        return map;
    }


    /**
     * @param dates 日期序列
     * @param flag  1-获取序列中最大日期，2-获取序列中最小日期
     * @return
     */
    public static Date getMinOrMaxDate(List<Date> dates, Integer flag) {
        if (null == dates || dates.size() == 0 || null == flag) {
            return null;
        }

        List<Date> dateNew = new ArrayList<>();
        for (Date date : dates) {
            if (null != date) {
                dateNew.add(date);
            }
        }

        //升序排序
        Collections.sort(dateNew, new Comparator<Date>() {

            @Override
            public int compare(Date o1, Date o2) {
                return o1.compareTo(o2);
            }
        });

        if (1 == flag) {
            return dateNew.get(dateNew.size() - 1);
        } else if (2 == flag) {
            return dateNew.get(0);
        } else {
            return null;
        }
    }


    //获取当年的每个季度月的最后日期
    public static List<Date> getSeasonsEndDateOfYear(Integer startYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();

        List<Date> result = new ArrayList<>();
        //第一季度 3月
        calendar.set(Calendar.YEAR, startYear);
        calendar.set(Calendar.MONTH, Calendar.MARCH);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        result.add(calendar.getTime());
        calendar.clear();
        //第二季度 6月
        calendar.set(Calendar.YEAR, startYear);
        calendar.set(Calendar.MONTH, Calendar.JUNE);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        result.add(calendar.getTime());
        calendar.clear();

        //第三季度 9月
        calendar.set(Calendar.YEAR, startYear);
        calendar.set(Calendar.MONTH, Calendar.SEPTEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        result.add(calendar.getTime());
        calendar.clear();

        //第四季度12月
        calendar.set(Calendar.YEAR, startYear);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        result.add(calendar.getTime());
        calendar.clear();

        return result;
    }

    //获取一年的第一天的日期
    public static Date getStartDateOfYear(Integer startYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, startYear);
        calendar.roll(Calendar.DAY_OF_YEAR, 0);
        return calendar.getTime();
    }

    //获取一年的最后一天的日期
    public static Date getEndDateOfYear(Integer startYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, startYear);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }

    private static void setMaxTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
        calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
        calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
        calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND));
    }
}